﻿using System;
using System.Collections.Generic;
using System.Text;

using System.ServiceModel;
using System.ServiceModel.Description;
using System.Threading;

namespace Future.WcfClient
{
    public class ClientProcess
    {
        private static ClientProcess _instance;
        private static int WcfChannelType = 0; // 0 = Tcp, 1 = Http

        public static ClientProcess shareXProcess()
        {
            if (_instance == null)
            {
                _instance = new ClientProcess();
                _instance.PingTimer.Change(0, Settings.SystemConfig.CurrentConfig.PingMS);
            }
            return _instance;
        }

        public static WcfClient GetWcfClient(string strIp, int iHttpPort, int iTcpPort)
        {
            WSHttpBinding httpBinding = new WSHttpBinding();
            httpBinding.Security.Mode = SecurityMode.None;
            EndpointAddress httpAddress = new EndpointAddress(string.Format(Settings.AllPath.S_Path_WcfServer_Http, strIp, iHttpPort));
            httpBinding.MaxBufferPoolSize = 104857600;
            httpBinding.MaxReceivedMessageSize = 104857600;
            httpBinding.ReceiveTimeout = new TimeSpan(0, 10, 0);
            httpBinding.SendTimeout = new TimeSpan(0, 10, 0);

            NetTcpBinding tcpBinding = new NetTcpBinding();
            tcpBinding.Security.Mode = SecurityMode.None;
            EndpointAddress tcpAddress = new EndpointAddress(string.Format(Settings.AllPath.S_Path_WcfServer_Tcp, strIp, iTcpPort));
            tcpBinding.MaxBufferSize = 104857600;
            tcpBinding.MaxReceivedMessageSize = 104857600;
            tcpBinding.MaxBufferPoolSize = 104857600;
            tcpBinding.ReceiveTimeout = new TimeSpan(0, 10, 0);
            tcpBinding.SendTimeout = new TimeSpan(0, 10, 0);

            try
            {
                WcfClient client;

                if (WcfChannelType == 0)
                {
                    client = new WcfClient(tcpBinding, tcpAddress);
                }
                else
                {
                    client = new WcfClient(httpBinding, httpAddress);
                }

                foreach (OperationDescription op in client.Endpoint.Contract.Operations)
                {
                    DataContractSerializerOperationBehavior dataContractBehavior = op.Behaviors.Find<DataContractSerializerOperationBehavior>()
                                as DataContractSerializerOperationBehavior;
                    if (dataContractBehavior != null)
                    {
                        dataContractBehavior.MaxItemsInObjectGraph = 1000000;
                    }
                }
                return client;
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
        }

        Timer _pingTimer; // ping 
        WcfClient _client;

        public WcfClient XClient
        {
            get
            {
                if (_client != null)
                {
                    if (_client.InnerChannel.State != CommunicationState.Opened)
                    {
                        _client = null;
                    }
                }

                if (_client == null)
                {
                    _client = GetWcfClient(Settings.SystemConfig.CurrentConfig.ServerIP, Settings.SystemConfig.CurrentConfig.ServerHttpPort, Settings.SystemConfig.CurrentConfig.ServerTcpPort);
                }

                return _client;
            }
        }

        public Timer PingTimer
        {
            get { return _pingTimer; }
        }

        public ClientProcess()
        {
            _pingTimer = new Timer(new TimerCallback(SendPing), null, System.Threading.Timeout.Infinite, Settings.SystemConfig.CurrentConfig.PingMS);
        }

        ~ClientProcess()
        {
        }

        void SendPing(object sender)
        {
            try
            {
                int ret = XClient.XPing(5);
            }
            catch (EndpointNotFoundException ex)
            {
                // 远程服务未发现
            }
            catch (Exception ex)
            {

                //MessageBox.Show(ex.Message);
            }
        }
    }
}
